﻿using Newtonsoft.Json;
using RestSharp;
using RestSharp.Serializers.NewtonsoftJson;
using System;
using System.Collections.Generic;

namespace DTU_Test;

/// <summary>
/// 平台接口（取设备信息，推送数据信息）
/// </summary>
public class ChengshuApiClient
{
    private string appId = "7d8184ded14935eb";
    private string appSecret = "778a188ede2dca2d";
    private string url = "http://47.98.56.119:8087/api/v1";

    /// <summary>
    /// 访问令牌
    /// </summary>
    protected string _accesstoken = "";

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="url"></param>
    /// <param name="appid"></param>
    /// <param name="appsecret"></param>
    /// <param name="logger"></param>
    public ChengshuApiClient(string url, string appid, string appsecret)
    {
        this.url = url;
        this.appId = appid;
        this.appSecret = appsecret;
    }

    public ChengshuApiClient()
    {
    }

    /// <summary>
    /// 登录到系统
    /// </summary>
    public void Login()
    {
        var request = new RestRequest("/login", Method.Post);
        var auth = new
        {
            appid = appId,
            appsecret = appSecret
        };
        request.AddJsonBody(auth);
        var clientEx = new RestClient(url!, configureSerialization: s => s.UseNewtonsoftJson());
        var responseEx = clientEx.ExecuteAsync(request);
        var content = responseEx.Result?.Content;
        var result = Helper.DeSerializeObject<ThirdPart_ApiResult<string>>(content);
        if (result != null && result.Code == 0)
        {
            _accesstoken = result.data!;
        }
        else
        {
            //_logger?.LogError($"登录系统失败{content}");
        }
    }

    /// <summary>
    /// 获取所有的设备信息
    /// </summary>
    public DeviceInfo[]? GetDevices()
    {
        var request = new RestRequest("/device/list", Method.Get);
        request.AddHeader("Authorization", $" 7DAC97FAA84B6F71");

        var clientEx = new RestClient(this.url!, configureSerialization: s => s.UseNewtonsoftJson());
        var restsharpResponse = clientEx.Execute(request);
        string content = restsharpResponse.Content ?? string.Empty;
        if (restsharpResponse.ErrorException != null)
        {
            // _logger?.LogError($"获取设备列表失败: {restsharpResponse.ErrorException.Message}");
            return null;
        }
        var r = Helper.FromJson<DeviceInfo[]>(content);

        if (r == null || r.Length == 0)
        {
            //_logger?.LogError($"获取设备列表失败: {content}");
            return null;
        }
        return r;
    }

    /// <summary>
    /// 推送数据
    /// </summary>
    /// <param name="deviceId"></param>
    /// <param name="telemetry"></param>
    public void PushDeviceData(string deviceId, TelemetryData telemetry)
    {
        var request = new RestRequest($"/telemetry/{deviceId}", Method.Post);
        //request.AddHeader("C-Token", $"cheng {_accesstoken}");
        request.AddJsonBody(telemetry);
        if (this.TryRequest(request, out string? result, out string? error))
        {
          //  _logger.LogInformation($"推送数据{telemetry.ToJson()}到平台成功{result}");
        }
        else
        {
           // _logger?.LogError($"推送数据到平台出错{error}");
        }
    }

    /// <summary>
    /// 推送在线状态
    /// </summary>
    /// <param name="deviceId"></param>
    /// <param name="online"></param>
    public void PushDeviceData(string deviceId, bool online)
    {
        var request = new RestRequest($"/telemetry/{deviceId}", Method.Post);
       // request.AddHeader("C-Token", $"cheng {_accesstoken}");
        var status = new
        {
            online = online
        };
        request.AddJsonBody(status);
        if (this.TryRequest(request, out string? result, out string? error))
        {
           // _logger.LogInformation($"推送在线状态到平台成功{result}");
        }
        else
        {
           // _logger?.LogError($"推送数据到平台出错{error}");
        }
    }

    /// <summary>
    /// Place a secure request and get back an object of type T.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="request"></param>
    /// <param name="result">Result object from the </param>
    ///  <param name="error">error info </param>
    /// <returns>T typed object response</returns>
    public bool TryRequest<T>(RestRequest request, out T? result, out string? error)
    {
        var responseContent = string.Empty;
        result = default;
        error = default;
        try
        {
             request.AddHeader("Authorization", $"Bearer {_accesstoken}");
            // Execute the authenticated REST API Call
            var clientEx = new RestClient(url!, configureSerialization: s => s.UseNewtonsoftJson());
            var restsharpResponse = clientEx.Execute(request);

            //Verify success
            if (restsharpResponse.ErrorException != null)
            {
                error = ($"ApiConnection.TryRequest({request.Resource}): Error: {restsharpResponse.ErrorException.Message}");

                return false;
            }

            if (!restsharpResponse.IsSuccessful)
            {
                error = ($"ApiConnect.TryRequest(): Content: {restsharpResponse.Content}");
            }

            responseContent = restsharpResponse.Content;
            var r = JsonConvert.DeserializeObject<ThirdPart_ApiResult<T>>(responseContent);

            if (r == null || !(r.Code == 00))
            {
                error = ($"ApiConnection.TryRequest(): Raw response: '{responseContent}'");
            }
            else
            {
                result = r.data;
                return true;
            }
        }
        catch (Exception err)
        {
            error = ($"ApiConnection.TryRequest({request.Resource}): Error: {err.Message}, Response content: {responseContent}");

            return false;
        }
        return false;
    }

    /// <summary>
    /// 根据卡号获取卡信息
    /// </summary>
    /// <param name="cardid"></param>
    public static CardInfo GetCardInfo(int cardid)
    {
        return new CardInfo() { cardid = cardid, xfvalue = 100, xfsubvalue = 100, ownername = "测试" };
    }

    /// <summary>
    /// 推送消费记录到平台
    /// </summary>
    /// <param name="consumptionrecord"></param>
    /// <returns></returns>
    public static ConsumptionRecordResp PushConsumptionRecord(ConsumptionRecord consumptionrecord)
    {
        return new ConsumptionRecordResp();
    }

    /// <summary>
    ///  查询卡号的消费记录
    /// </summary>
    /// <param name="cardid"></param>
    /// <param name="sn"></param>
    /// <returns></returns>
    public static ConsumptionRecordResp GetConsumptionRecord(int cardid, string sn)
    {
        return new ConsumptionRecordResp();
    }
}

/// <summary>
/// 接口返回结果
/// </summary>
public class ThirdPart_ApiResult<T>
{
    /// <summary>
    /// 返回的数据
    /// </summary>
    public T? data { get; set; }

    /// <summary>
    /// 代码
    /// </summary>
    public int Code { get; set; }

    /// <summary>
    /// 消息内容
    /// </summary>
    public string? message { get; set; }
}

/// <summary>
/// 卡信息
/// </summary>
public record CardInfo
{
    /// <summary>
    /// 卡号
    /// </summary>
    public int cardid;
    /// <summary>
    /// 持有者姓名
    /// </summary>
    public string? ownername;

    /// <summary>
    /// 现金余额
    /// </summary>
    public int xfvalue;

    /// <summary>
    /// 补贴余额
    /// </summary>
    public int xfsubvalue;
}

/// <summary>
/// 消费记录
/// </summary>
public record ConsumptionRecord
{
    /// <summary>
    /// 卡号
    /// </summary>
    public int cardid;
    /// <summary>
    /// 设备号
    /// </summary>
    public int machinecode;
    /// <summary>
    /// 消费金额
    /// </summary>
    public int amount;
    /// <summary>
    /// 消费序列号
    /// </summary>
    public string? sn;
}

/// <summary>
/// 消费记录回复
/// </summary>
public record ConsumptionRecordResp
{
    /// <summary>
    /// 卡号
    /// </summary>
    public int cardid;
    /// <summary>
    /// 持有者姓名
    /// </summary>
    public string? ownername;
    /// <summary>
    /// 现金余额
    /// </summary>
    public int xfvalue;
    /// <summary>
    /// 补贴余额
    /// </summary>
    public int xfsubvalue;
    /// <summary>
    /// 现金消费金额
    /// </summary>
    public int amount;
    /// <summary>
    /// 补贴消费金额
    /// </summary>
    public int subamount;
}

/// <summary>
/// 设备信息（modbus标准透传设备）
/// </summary>
public class DeviceInfo
{
    /// <summary>
    /// 设备名称
    /// </summary>
    public string? Name { get; set; }

    /// <summary>
    /// 编码
    /// </summary>
    public string? No { get; set; }

    /// <summary>
    /// 设备型号
    /// </summary>
    public string? Model { get; set; }

    /// <summary>
    /// 设备模板(存储数据点位信息）
    /// </summary>
    public ModbusDataPoint[]? Profile { get; set; }
}

public class TelemetryData
{
    /// <summary>
    /// 时间戳
    /// </summary>
    [JsonProperty("ts")]
    public long ts;

    [JsonIgnore]
    public DateTimeOffset Timestamp
    {
        get => DateTimeOffset.FromUnixTimeMilliseconds(ts);
        set => ts = value.ToUnixTimeMilliseconds();
    }

    /// <summary>
    /// 值
    /// </summary>
    [JsonProperty("values")]
    public KeyValueContent Values = new KeyValueContent();
}

public class KeyValueContent : Dictionary<string, object>
{
}